/*
 * Copyright 2023, Haiku, Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 *
 * 龙芯3A6000 LS7A2000桥片 PCIe配置空间访问方法
 */

#ifndef _LOONGSON_PCH_PCI_H
#define _LOONGSON_PCH_PCI_H

#include <KernelExport.h>
#include <PCI.h>
#include <SupportDefs.h>

// LS7A2000 PCIe配置空间基地址
#define LS7A_PCH_PCI_CONFIG_BASE 0x20000000
#define LS7A_PCH_PCI_CONFIG_SIZE 0x10000000

// PCIe配置空间访问方法
#define LS7A_PCH_PCI_CONFIG_ADDR(bus, dev, func, reg) \
    (LS7A_PCH_PCI_CONFIG_BASE | ((bus) << 16) | ((dev) << 11) | ((func) << 8) | (reg))

// 函数声明
status_t loongson_pch_pci_init(void);
void loongson_pch_pci_uninit(void);

// PCIe配置空间读写函数
uint8 loongson_pch_pci_read_config_8(uint8 bus, uint8 device, uint8 function, uint8 reg);
void loongson_pch_pci_write_config_8(uint8 bus, uint8 device, uint8 function, uint8 reg, uint8 value);

uint16 loongson_pch_pci_read_config_16(uint8 bus, uint8 device, uint8 function, uint8 reg);
void loongson_pch_pci_write_config_16(uint8 bus, uint8 device, uint8 function, uint8 reg, uint16 value);

uint32 loongson_pch_pci_read_config_32(uint8 bus, uint8 device, uint8 function, uint8 reg);
void loongson_pch_pci_write_config_32(uint8 bus, uint8 device, uint8 function, uint8 reg, uint32 value);

// DMA地址映射函数
phys_addr_t loongson_pch_pci_map_dma_memory(phys_addr_t physical_address, size_t size);
void loongson_pch_pci_unmap_dma_memory(phys_addr_t mapped_address, size_t size);

#endif // _LOONGSON_PCH_PCI_H